package megamu.mesh;

/*
 * Copyright 2011 James Humphreys. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY James Humphreys ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of James Humphreys.
 */

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;

import quickhull3d.Point3d;

import com.jellyfishumbrella.GL.Vector3d;
import com.jellyfishumbrella.GL.Vertex;

// used both for sites and for vertices
public class Site {// extends Vertex {
	public Vertex						vert		= new Vertex();
	public boolean						doVoronoi	= false;
	public int							index		= -1;								// signifies that this site has not been properly initialized and voronoi'ed
	public int							iIndex		= -1;
	public int							jIndex		= -1;
	public boolean						isCenter	= false;
	public int							sitenbr		= 0;
// public ArrayList<Site> links;
	public LinkedHashSet<Site>			neighbors	= new LinkedHashSet<Site>();
	public LinkedHashMap<Site, Edge>	edges		= new LinkedHashMap<Site, Edge>();

	// key is neighbor, separated by this edge

	public boolean						checked		= false;
	public Region						region;

	public Site() {
		// super(0, 0, 0);
		vert = new Vertex(0, 0, 0);
	}

	public Site(double X, double Z) {
		// super(X, 0.0, Z);
		vert = new Vertex(X, 0, Z);
	}

	public Site(int index, Vertex V) {
		// super(V.x, V.y, V.z);
		this.index = index;
		vert = V;
	}

	public Site(int index, Vector3d V) {
		// super(V.x, V.y, V.z);
		this.index = index;
		vert = new Vertex(V.x, V.y, V.z);
	}

	public Site(Point3d P) {
		// super(V.x, V.y, V.z);
		Vertex V = new Vertex(P.x, P.y, P.z);
		vert = V;
	}

	public Site(int index, Point3d P) {
		this.index = index;
		Vertex V = new Vertex(P.x, P.y, P.z);
		vert = V;
	}
	
	public void addNeighbor(Site neighborSite){
		this.neighbors.add(neighborSite);
		neighborSite.neighbors.add(this);
	}

	public Site nextUncheckedSite() {
		//for (int i = 0; i < links.size(); i++) {
			//Site testSite = links.get(i);
		for(Site testSite : neighbors){
			if (!testSite.checked) {
				return testSite;
			}
		}
		return null;
	}

	public Corner toCorner() {
		return new Corner(x(), y(), z());
	}

	public void setX(double X) {
		vert.setX(X);
	}

	public void setY(double Y) {
		vert.setY(Y);
	}

	public void setZ(double Z) {
		vert.setZ(Z);
	}

	public double x() {
		return vert.x();
	}

	public double y() {
		return vert.y();
	}

	public double z() {
		return vert.z();
	}

	public String toString() {
		String str = "";
		str += index + "| " + vert.x() + "," + vert.y() + "," + vert.z();// + " | " + i_index + " | " + j_index;
		return str;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + index;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Site other = (Site) obj;
		if (index != other.index)
			return false;
		return true;
	}
}
